package com.jcl.cloud.services.unicrawler.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jcl.cloud.common.service.exception.JclCrawlException;
import com.jcl.cloud.services.gateway.common.task.BuyResumeReq;
import com.jcl.cloud.services.gateway.common.task.BuyResumeRsp;
import com.jcl.cloud.services.unicrawler.common.dto.CrawlTask;
import com.jcl.cloud.services.unicrawler.common.dto.GrabRequest;
import com.jcl.cloud.services.unicrawler.common.dto.GrabResult;
import com.jcl.cloud.services.unicrawler.common.util.JedisUtil;
import com.jcl.cloud.services.unicrawler.util.AccountUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisCommands;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisException;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

public class CrawlerTaskHandlerRedisImpl implements CrawlerTaskHandler {

    private static final Logger logger = LoggerFactory.getLogger(CrawlerTaskHandlerRedisImpl.class);
    private JedisPool jedisPool;
    private JedisCluster jedisCluster;


    public CrawlerTaskHandlerRedisImpl(JedisPool jedisPool, JedisCluster jedisCluster) {
        this.jedisPool = jedisPool;
        this.jedisCluster = jedisCluster;
    }


    @Override
    public void addTask(CrawlTask crawlTask) throws JclCrawlException {
        JedisCommands commands = null;
        String crawlerId = crawlTask.getCrawlerId();
        if (null == crawlerId) {
            throw new JclCrawlException();
        } else {
            try {
                commands = JedisUtil.getJedisCommands(jedisCluster, jedisPool);
                Jedis jedis = (Jedis) commands;
                String tenantId = crawlTask.getTenantId();
                String accountKey = crawlTask.getAccountKey();
                String cron = crawlTask.getCron();
                String taskType = crawlTask.getTaskType();
                String siteCode = crawlTask.getSiteCode();

                //通过crawlerId保存爬虫信息
                Map<String, String> taskInfoMap = new HashMap();
                taskInfoMap.put("tenantId", tenantId);
                taskInfoMap.put("accountKey", accountKey);
                taskInfoMap.put("nextExecuteTime", String.valueOf(System.currentTimeMillis()));
                taskInfoMap.put("cron", cron);
                taskInfoMap.put("taskType", taskType);
                taskInfoMap.put("siteCode", siteCode);
                taskInfoMap.put("account", crawlTask.getAccount());
                taskInfoMap.put("userName", crawlTask.getUserName());
                taskInfoMap.put("passWord", crawlTask.getPassWord());

                //taskInfoMap.put("taskParam", JSON.toJSONString(crawlTask));
                jedis.hmset("unicrawler:task:info:" + crawlerId, taskInfoMap);
                //放入任务队列
                jedis.lpush("unicrawler:tasks:all", crawlerId);


                Map accountInfo = new HashMap();
                accountInfo.put("crawlerId", crawlerId);
                accountInfo.put("account", crawlTask.getAccount());
                accountInfo.put("userName", crawlTask.getUserName());
                accountInfo.put("passWord", crawlTask.getPassWord());


                //保存用户信息与爬虫的映射关系,user-manager-server进行管理
                // jedis.lpush("usermgr:tenant:list", tenantId);
                // jedis.hset("usermgr:accinfo:map:" + tenantId, accountKey, JSON.toJSONString(accountInfo));

                jedis.hset("usermgr:account-crawler:map", accountKey, JSON.toJSONString(accountInfo));


                logger.debug("Task created, taskId - {}", crawlTask.getTaskId());
            } catch (JedisException e) {
                e.printStackTrace();
                throw new JclCrawlException();
            } finally {
                JedisUtil.releaseJedisConnection(commands);
            }
        }
    }

    @Override
    public GrabResult grabTask(GrabRequest grabRequest) throws JclCrawlException {


        JedisCommands commands = null;
        String crawlerId = "";
        GrabResult grabResult = new GrabResult();
        grabResult.setTraceId(grabRequest.getTraceId());
        try {
            commands = JedisUtil.getJedisCommands(jedisCluster, jedisPool);
            Jedis jedis = (Jedis) commands;
            crawlerId = jedis.rpop("unicrawler:tasks:all");
            if (null == crawlerId) {
                grabResult.setMsg("no task.");
            } else {

                List paramList = jedis.hmget("unicrawler:task:info:" + crawlerId, "cron", "nextExecuteTime");

                grabResult.setCrawlerId(crawlerId);
                grabResult.setCron((String) paramList.get(0));
                grabResult.setNextExecuteTime((String) paramList.get(1));
            }
        } catch (JedisException e) {
            e.printStackTrace();
            throw new JclCrawlException();
        } finally {
            JedisUtil.releaseJedisConnection(commands);
        }
        return grabResult;
    }

    @Override
    public BuyResumeRsp buyResume(BuyResumeReq buyResumeReq) throws JclCrawlException {
        JedisCommands commands = null;
        BuyResumeRsp buyResumeRsp = new BuyResumeRsp();

        try {
            commands = JedisUtil.getJedisCommands(jedisCluster, jedisPool);
            Jedis jedis = (Jedis) commands;

            String account = buyResumeReq.getAccount();
            String userName = buyResumeReq.getUserName();
            String passWord = buyResumeReq.getPassWord();
            String siteCode = buyResumeReq.getSiteCode();

            if (StringUtils.isBlank(siteCode)) {
                buyResumeRsp.setStatus(-1);
                buyResumeRsp.setMsg("参数异常，siteCode为空，无法购买");

                return buyResumeRsp;
            }


            String accountKey = AccountUtils.getAccountKey(account, userName, passWord);


            //判断该用户是否有正在运行的爬虫
            String crawlerInfo = jedis.hget("usermgr:account-crawler:map", accountKey);
            if (StringUtils.isBlank(crawlerInfo)) {
                logger.info(String.format("account = %s ,userName = %s ,passWord = %s accountKey = %s  的账号信息无正在运行的爬虫", account, userName, passWord, accountKey));
                buyResumeRsp.setStatus(-1);
                buyResumeRsp.setMsg("此账号信息无正在运行的后台爬虫，无法购买");
            } else {


                Map map = JSON.toJavaObject(JSON.parseObject(crawlerInfo), Map.class);
                String crawlerId = (String) map.get("crawlerId");
                logger.info(String.format("account = %s ,userName = %s ,passWord = %s accountKey = %s  的账号信息对应的后台爬虫为crawlerId = %s", account, userName, passWord, accountKey, crawlerId));

                //0表示有正在运行的后台爬虫，-1表示没有
                buyResumeRsp.setStatus(0);
                buyResumeRsp.setMsg("后台购买中...");

                String taskIdForBuy = UUID.randomUUID().toString();
                buyResumeRsp.setTaskIdForBuy(taskIdForBuy);


                //存入购买队列中
                Map dataMap = new HashMap();
                dataMap.put("taskIdForBuy", taskIdForBuy);
                dataMap.put("data", buyResumeReq);
                dataMap.put("crawlerId", crawlerId);
                dataMap.put("tenantId", buyResumeReq.getTenantId());


                //放入购买队列
                jedis.lpush("unicrawler:buy-resume:tasks", JSON.toJSONString(dataMap));
                logger.info(String.format("taskIdForBuy = %s的购买请求已经放入队列中，请求信息为：%s", taskIdForBuy, JSON.toJSONString(dataMap)));
            }

        } catch (JedisException e) {
            e.printStackTrace();
            throw new JclCrawlException();
        } finally {
            JedisUtil.releaseJedisConnection(commands);
        }

        return buyResumeRsp;
    }


    @Override
    public void buyResume(String src) {

        if (StringUtils.isBlank(src)) {
            return;
        }

        JedisCommands commands = null;
        try {
            commands = JedisUtil.getJedisCommands(jedisCluster, jedisPool);
            Jedis jedis = (Jedis) commands;


            JSONObject srcJO = JSON.parseObject(src);
            JSONObject outDataJO = srcJO.getJSONObject("data");
            JSONArray inDataArr = outDataJO.getJSONArray("data");
            for (Object object : inDataArr) {
                JSONObject jo = (JSONObject) object;
                BuyResumeReq buyResumeReq = JSON.toJavaObject(jo, BuyResumeReq.class);
                String accountKey = (String) buyResumeReq.getBuyResumeContext().get("accountKey");
                if (StringUtils.isNotBlank(accountKey)) {
                    String crawlerInfo = jedis.hget("usermgr:account-crawler:map", accountKey);
                    if (StringUtils.isBlank(crawlerInfo)) {
                        logger.info(String.format("accountKey = %s的账户未在运行中..."));
                    } else {

                        Map map = JSON.toJavaObject(JSON.parseObject(crawlerInfo), Map.class);
                        String crawlerId = (String) map.get("crawlerId");
                        logger.info(String.format(" accountKey = %s  的账号信息对应的后台爬虫为crawlerId = %s", accountKey, crawlerId));


                        String taskIdForBuy = UUID.randomUUID().toString();


                        //存入购买队列中
                        Map dataMap = new HashMap();
                        dataMap.put("taskIdForBuy", taskIdForBuy);
                        dataMap.put("data", buyResumeReq);
                        dataMap.put("crawlerId", crawlerId);
                        dataMap.put("tenantId", buyResumeReq.getTenantId());


                        //放入购买队列
                        jedis.lpush("unicrawler:buy-resume:tasks", JSON.toJSONString(dataMap));
                        logger.info(String.format("taskIdForBuy = %s的购买请求已经放入队列中，请求信息为：%s", taskIdForBuy, JSON.toJSONString(dataMap)));
                    }
                }else {
                    logger.info("请求信息中无accountKey，详细请求信息如下：" + buyResumeReq.toString());
                }
            }
        } catch (Exception e) {
            logger.error("将购买信息放入队列发生异常："+e.getMessage(),e);
        }finally {
            JedisUtil.releaseJedisConnection(commands);
        }



    }

    @Override
    public void addTask(String src) {

        if(StringUtils.isBlank(src)){
            return;
        }

        JedisCommands commands = null;

        commands = JedisUtil.getJedisCommands(jedisCluster, jedisPool);
        Jedis jedis = (Jedis) commands;








    }


    public static void main(String[] args) {
        String src = "{\n" +
                "    \"msg\": \"OK\",\n" +
                "    \"code\": \"200\",\n" +
                "    \"data\": {\n" +
                "        \"total\": 3,\n" +
                "        \"curPage\": 1,\n" +
                "        \"data\": [\n" +
                "            {\n" +
                "                \"taskType\": \"buy-resume\",\n" +
                "                \"siteCode\": \"zlzp\",\n" +
                "                \"tenantId\": \"89C45BAC08310E278B530A2138B85917\",\n" +
                "                \"buyResumeContext\": \"{\\\"resumeNo\\\":\\\"wMIbzVSfs2r1h0dkNS0KLA\\\",\\\"Referer\\\":\\\"https://rd5.zhaopin.com/resume/detail?keyword=java&resumeNo=wMIbzVSfs2r1h0dkNS0KLA_1_1%3BE5BF8D7EAE8EEA614F7486C86993889B%3B1540791666783&openFrom=1\\\",\\\"resumeNo_k_t\\\":\\\"wMIbzVSfs2r1h0dkNS0KLA_1_1%3BE5BF8D7EAE8EEA614F7486C86993889B%3B1540791666783\\\",\\\"accountKey\\\":\\\"3A565D15BC8FEE99C351E42FA5506744\\\"}\"\n" +
                "            },\n" +
                "            {\n" +
                "                \"taskType\": \"buy-resume\",\n" +
                "                \"siteCode\": \"zlzp\",\n" +
                "                \"tenantId\": \"89C45BAC08310E27999962EA925C9174\",\n" +
                "                \"buyResumeContext\": \"{\\\"resumeNo\\\":\\\"rpzfzJw4K7fV5VehAJogEg\\\",\\\"Referer\\\":\\\"https://rd5.zhaopin.com/resume/detail?keyword=java&resumeNo=rpzfzJw4K7fV5VehAJogEg_1_1%3B70168760A3018A2AAF7B02EBC54FB7B9%3B1540791666819&openFrom=1\\\",\\\"resumeNo_k_t\\\":\\\"rpzfzJw4K7fV5VehAJogEg_1_1%3B70168760A3018A2AAF7B02EBC54FB7B9%3B1540791666819\\\",\\\"accountKey\\\":\\\"3A565D15BC8FEE99C351E42FA5506744\\\"}\"\n" +
                "            },\n" +
                "            {\n" +
                "                \"taskType\": \"buy-resume\",\n" +
                "                \"siteCode\": \"zlzp\",\n" +
                "                \"tenantId\": \"89C45BAC08310E27B9197A1DA5B5E247\",\n" +
                "                \"buyResumeContext\": \"{\\\"resumeNo\\\":\\\"PB3RsWKdtgv1h0dkNS0KLA\\\",\\\"Referer\\\":\\\"https://rd5.zhaopin.com/resume/detail?keyword=java&resumeNo=PB3RsWKdtgv1h0dkNS0KLA_1_1%3B448522ADBBFF20663A71EFA8FC68FD2F%3B1540791692113&openFrom=1\\\",\\\"resumeNo_k_t\\\":\\\"PB3RsWKdtgv1h0dkNS0KLA_1_1%3B448522ADBBFF20663A71EFA8FC68FD2F%3B1540791692113\\\",\\\"accountKey\\\":\\\"3A565D15BC8FEE99C351E42FA5506744\\\"}\"\n" +
                "            }\n" +
                "        ],\n" +
                "        \"rowSize\": 50\n" +
                "    },\n" +
                "    \"type\": \"success\"\n" +
                "}";





        JSONObject srcJO = JSON.parseObject(src);
        JSONObject outDataJO = srcJO.getJSONObject("data");
        JSONArray inDataArr = outDataJO.getJSONArray("data");
        for (Object object : inDataArr) {
            JSONObject jo = (JSONObject) object;
            BuyResumeReq buyResumeReq = JSON.toJavaObject(jo, BuyResumeReq.class);
            String accountKey = (String) buyResumeReq.getBuyResumeContext().get("accountKey");
            if (StringUtils.isNotBlank(accountKey)) {
                //String crawlerInfo = jedis.hget("usermgr:account-crawler:map", accountKey);
                String crawlerInfo = "12313";
                if (StringUtils.isBlank(crawlerInfo)) {
                    logger.info(String.format("accountKey = %s的账户未在运行中..."));
                } else {

                    Map map = JSON.toJavaObject(JSON.parseObject(crawlerInfo), Map.class);
                    String crawlerId = (String) map.get("crawlerId");
                    logger.info(String.format(" accountKey = %s  的账号信息对应的后台爬虫为crawlerId = %s", accountKey, crawlerId));


                    String taskIdForBuy = UUID.randomUUID().toString();


                    //存入购买队列中
                    Map dataMap = new HashMap();
                    dataMap.put("taskIdForBuy", taskIdForBuy);
                    dataMap.put("data", buyResumeReq);
                    dataMap.put("crawlerId", crawlerId);
                    dataMap.put("tenantId", buyResumeReq.getTenantId());


                    //放入购买队列
                    //jedis.lpush("unicrawler:buy-resume:tasks", JSON.toJSONString(dataMap));
                    logger.info(String.format("taskIdForBuy = %s的购买请求已经放入队列中，请求信息为：%s", taskIdForBuy, JSON.toJSONString(dataMap)));
                }
            }else {
                logger.info("请求信息中无accountKey，详细请求信息如下：" + buyResumeReq.toString());
            }
        }

    }


}
